package pers.lt.tools;

import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

public  class RandomStrg
{
    private Integer length;
    private String randomstr;
    private boolean allchars;
    private HashMap hmap;
    private ArrayList lower;
    private ArrayList upper;
    private char single[];
    private int singlecount;
    private boolean singles;
    private String algorithm;
    private String provider;
    private boolean secure;
    private Random random;
    private SecureRandom secrandom;
    private static long id = 1L;

    public RandomStrg()
    {
        length = new Integer(8);
        allchars = false;
        lower = null;
        upper = null;
        single = null;
        singlecount = 0;
        singles = false;
        algorithm = null;
        provider = null;
        secure = false;
        random = null;
        secrandom = null;
    }

    public void setLength(int count)
    {
        length = new Integer(count);
    }

    private final float getFloat()
    {
        if(random == null)
            return secrandom.nextFloat();
        else
            return random.nextFloat();
    }

    public final void generateRandomObject()
        throws Exception
    {
        if(secure)
            try
            {
                if(provider != null)
                    random = SecureRandom.getInstance(algorithm, provider);
                else
                    random = SecureRandom.getInstance(algorithm);
            }
            catch(NoSuchAlgorithmException ne)
            {
                throw new Exception(ne.getMessage());
            }
            catch(NoSuchProviderException pe)
            {
                throw new Exception(pe.getMessage());
            }
        else
            random = new Random();
    }

    private final void generaterandom()
    {
        if(allchars)
        {
            for(int i = 0; i < length.intValue(); i++)
                randomstr = randomstr + (new Character((char)(34 + (int)(getFloat() * 93F)))).toString();

        } else
        if(singles)
        {
            if(upper.size() == 3)
            {
                for(int i = 0; i < length.intValue(); i++)
                    if((int)(getFloat() * 100F) % 2 == 0)
                    {
                        if((int)(getFloat() * 100F) % 2 == 0)
                            randomstr = randomstr + randomSingle().toString();
                        else
                            randomstr = randomstr + randomChar((Character)lower.get(2), (Character)upper.get(2)).toString();
                    } else
                    if((int)(getFloat() * 100F) % 2 == 0)
                        randomstr = randomstr + randomChar((Character)lower.get(1), (Character)upper.get(1)).toString();
                    else
                        randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

            } else
            if(upper.size() == 2)
            {
                for(int i = 0; i < length.intValue(); i++)
                    if((int)(getFloat() * 100F) % 2 == 0)
                        randomstr = randomstr + randomSingle().toString();
                    else
                    if((int)(getFloat() * 100F) % 2 == 0)
                        randomstr = randomstr + randomChar((Character)lower.get(1), (Character)upper.get(1)).toString();
                    else
                        randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

            } else
            if(upper.size() == 1)
            {
                for(int i = 0; i < length.intValue(); i++)
                    if(((int)getFloat() * 100) % 2 == 0)
                        randomstr = randomstr + randomSingle().toString();
                    else
                        randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

            } else
            {
                for(int i = 0; i < length.intValue(); i++)
                    randomstr = randomstr + randomSingle().toString();

            }
        } else
        if(upper.size() == 3)
        {
            for(int i = 0; i < length.intValue(); i++)
                if((int)(getFloat() * 100F) % 2 == 0)
                    randomstr = randomstr + randomChar((Character)lower.get(2), (Character)upper.get(2)).toString();
                else
                if((int)(getFloat() * 100F) % 2 == 0)
                    randomstr = randomstr + randomChar((Character)lower.get(1), (Character)upper.get(1)).toString();
                else
                    randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

        } else
        if(upper.size() == 2)
        {
            for(int i = 0; i < length.intValue(); i++)
                if((int)(getFloat() * 100F) % 2 == 0)
                    randomstr = randomstr + randomChar((Character)lower.get(1), (Character)upper.get(1)).toString();
                else
                    randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

        } else
        {
            for(int i = 0; i < length.intValue(); i++)
                randomstr = randomstr + randomChar((Character)lower.get(0), (Character)upper.get(0)).toString();

        }
    }

    private final Character randomSingle()
    {
        return new Character(single[(int)(getFloat() * (float)singlecount - 1.0F)]);
    }

    private final Character randomChar(Character lower, Character upper)
    {
        char low = lower.charValue();
        char up = upper.charValue();
        int tempval = (int)((float)low + getFloat() * (float)(up - low));
        return new Character((char)tempval);
    }

    public final String getRandom()
    {
        randomstr = new String();
        generaterandom();
        if(hmap != null)
        {
            for(; hmap.containsKey(randomstr); generaterandom());
            hmap.put(randomstr, null);
        }
        return randomstr;
    }

    public final void setRanges(ArrayList low, ArrayList up)
    {
        lower = low;
        upper = up;
    }

    public final void setHmap(HashMap map)
    {
        hmap = map;
    }

    public final void setLength(String value)
    {
        length = new Integer(value);
    }

    public final void setAlgorithm(String value)
    {
        algorithm = value;
        secure = true;
    }

    public final void setProvider(String value)
    {
        provider = value;
    }

    public final void setAllchars(boolean value)
    {
        allchars = value;
    }

    public final void setSingle(char chars[], int value)
    {
        single = chars;
        singlecount = value;
        singles = true;
    }

    public final void setCharset(String value)
    {
        boolean more = true;
        lower = new ArrayList(3);
        upper = new ArrayList(3);
        if(value.compareTo("all") == 0)
        {
            allchars = true;
            more = false;
        } else
        if(value.charAt(1) == '-' && value.charAt(0) != '\\')
            while(more && value.charAt(1) == '-' && value.charAt(0) != '\\') 
            {
                lower.add(new Character(value.charAt(0)));
                upper.add(new Character(value.charAt(2)));
                if(value.length() <= 3)
                    more = false;
                else
                    value = value.substring(3);
            }
        if(more)
        {
            single = new char[30];
            for(StringTokenizer tokens = new StringTokenizer(value); tokens.hasMoreTokens();)
            {
                String token = tokens.nextToken();
                if(token.length() > 1)
                    single[singlecount++] = '-';
                single[singlecount++] = token.charAt(0);
            }

        }
        if(lower == null && single == null)
            setCharset("a-zA-Z0-9");
    }
   public static String getGUID32(int piNumber){
	   String ls_Guid =getGUID(piNumber);
	   ls_Guid=ls_Guid.replaceAll("\\-","");
	   ls_Guid=ls_Guid.replaceAll("\\{","");
	   ls_Guid=ls_Guid.replaceAll("\\}","");
	   return ls_Guid;
   }
   public static String getGUID32(){
     return getGUID32(-1);
   }
    public static String getGUID()
    {
        return getGUID(-1);
    }

    public static String getGUID(int piNumber)
    {
    	try{
    		
	        String dsNumber;
	        String dsDateTime;
	        RandomStrg rstr = new RandomStrg();
	        rstr.setCharset("A-F0-9");
	        rstr.setLength(12);
	        rstr.generateRandomObject();
	        dsNumber = rstr.getRandom();
	        if(piNumber < 0)
	            dsNumber = (String.valueOf(getNextId())+"0000").substring(0,4) + "-" + dsNumber;
	        else
	            dsNumber = (String.valueOf(piNumber) +"0000").substring(0,4) + "-" + dsNumber;
	        Date d = new Date();
	        String ls_DateFormat = "yyyyMMdd-HHmm-ssSSS";
	        DateFormat df = new SimpleDateFormat(ls_DateFormat);
	        dsDateTime = df.format(d).substring(0, 18);
	        return "{" + dsDateTime + "-" + dsNumber + "}";
        }catch(Exception ex){
           // Logger.log("Error in RandomStrg.getGuid()"+ ex.toString(),"error");	
            return "";
        }
        
    }

    private static synchronized long getNextId()
    {
        id++;
        return id;
    }
    public static void main(String[] args){
         for(int i=0;i<100;i++){
	       RandomStrg rd=new RandomStrg();
	       String guid=rd.getGUID32();
	       System.out.println(guid.length()  +"\n"+guid);
         }
    }
}
